package com.ysq.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.ysq.common.BaseContext;
import com.ysq.controller.exception.CustomException;
import com.ysq.entity.*;
import com.ysq.mapper.*;
import com.ysq.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * ClassName: OrderServiceImpl
 * Package: com.ysq.service.impl
 * Description:
 *
 * @Author YSQ
 * @Create 2023/1/13 13:30
 */
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper mapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;
    @Autowired
    private AddressBookMapper addressBookMapper;
    @Autowired
    private UserMapper userMapper;

    @Override
    public boolean submit(Orders order) {
        //当前有的参数只有前端传来的三个, 我们要完成对两个表的数据更新, 还要插入当前用户购物车里面的内容
        //比如下单了什么东西啊, 金额是多少啊等等, 那么这里我们还要自动注入ShoppingCartMapper
        //还要更新order_detail表, 所以还要自动注入OrderDetailMapper
        //我们还要根据用户ID查到用户的地址信息保存到订单表里, 所以还要自动注入AddressBookMapper
        //我们还要把当前用户的个人信息插入到表里, 所以还要自动注入UserMapper

        //我们先拿到购物车里面的信息
        //1. 获取当前用户ID
        Long currentId = BaseContext.getCurrentId();
        //2. 构造条件构造器
        //我们要执行的SQL语句: select * from shopping_cart where user_id = ?;
        LambdaQueryWrapper<ShoppingCart> lqwShoppingCart = new LambdaQueryWrapper<>();
        lqwShoppingCart.eq(ShoppingCart::getUserId, currentId);//where user_id = ?
        //3. 拿到购物车信息
        List<ShoppingCart> shoppingCarts = shoppingCartMapper.selectList(lqwShoppingCart);
        //4. 这里可以来个校验
        if (shoppingCarts == null) {
            throw new CustomException("购物车数据为空, 不能下单~~~");
        }

        //再拿地址信息, 我们现在有了前端传来的地址ID, 直接根据ID查询即可
        //地址ID就在order的addressBookId属性里
        //1. 构造条件构造器
        //我们要执行的SQL语句: select * from address_book where id = ?;
        LambdaQueryWrapper<AddressBook> lqwAddressBook = new LambdaQueryWrapper<>();
        lqwAddressBook.eq(AddressBook::getId, order.getAddressBookId());//where id = ?
        //2. 拿到地址信息
        AddressBook addressBook = addressBookMapper.selectOne(lqwAddressBook);
        //3. 这里可以来个校验
        if (addressBook == null) {
            throw new CustomException("地址信息有误, 不能下单~~~");
        }

        //再拿当前下单的用户的用户信息, 我们已经拿到了当前用户ID, 那么就可以直接根据ID查询
        User user = userMapper.selectById(currentId);

        //现在信息都拿完了, 现在要做的就是把订单表和订单明细表对象塞满!!!
        //先搞一个订单ID出来, 用工具类, 这个是MyBatisPlus提供的
        long orderId = IdWorker.getId();
        //再搞个金额出来, 也是用的工具类
        //原子整数类, 可以保证线程安全
        AtomicInteger amount = new AtomicInteger(0);//总金额
        //总金额要通过遍历购物车才能算出来
        //而在遍历购物车的过程中就可以完成对订单详细表的设置属性操作, 所以合二为一
        //向订单详细表设置属性, 同时计算金额
        List<OrderDetail> orderDetailList = shoppingCarts.stream().map((item) -> {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(orderId);//订单ID
            orderDetail.setName(item.getName());//商品名称
            orderDetail.setImage(item.getImage());//图片
            orderDetail.setDishId(item.getDishId());//菜品ID
            orderDetail.setSetmealId(item.getSetmealId());//套餐ID
            orderDetail.setDishFlavor(item.getDishFlavor());//菜品口味
            orderDetail.setNumber(item.getNumber());//商品数量
            orderDetail.setAmount(item.getAmount());//商品单价
            amount.addAndGet(item.getAmount().multiply(new BigDecimal(item.getNumber())).intValue());//商品总价, 单价*数量
            return orderDetail;
        }).collect(Collectors.toList());

        //向订单表设置属性
        order.setId(orderId);//订单ID
        order.setNumber(String.valueOf(orderId));//订单号, 把订单ID转成String类型
        order.setStatus(2);//订单状态, 2=待配送
        order.setUserId(currentId);//用户ID
        order.setOrderTime(LocalDateTime.now());//下单时间
        order.setCheckoutTime(LocalDateTime.now());//结账时间
        order.setAmount(new BigDecimal(amount.get()));//实收金额, 总金额
        order.setPhone(addressBook.getPhone());//手机号
        order.setUserName(user.getName());//用户名
        order.setConsignee(addressBook.getConsignee());//收货人
        order.setAddress((addressBook.getProvinceName() == null ? "" : addressBook.getProvinceName()) +
                (addressBook.getCityName() == null ? "" : addressBook.getCityName()) +
                (addressBook.getDistrictName() == null ? "" : addressBook.getDistrictName()) +
                (addressBook.getDetail() == null ? "" : addressBook.getDetail()));

        //向数据库中的orders订单表和order_detail表插入数据
        int row = mapper.insert(order);
        for (OrderDetail orderDetail : orderDetailList) {
            row += orderDetailMapper.insert(orderDetail);
        }
        return row > 0;
    }
}
